#![forbid(unsafe_code)]

// 导入安全FFI模块
use safe_ffi::{SafeMemoryBuffer, SafeCString, FFIResult, FFIError};
use safe_ffi::callback::{register_string_callback, execute_callback, unregister_callback};
use safe_ffi::config::{Config, ConfigValue, SafeZenrsConfig};
use safe_ffi::utils::{StringUtils, NumberUtils, CopyUtils};
use std::ptr;
use std::sync::{Arc, Mutex};

// 测试SafeMemoryBuffer的基本功能
#[test]
fn test_safe_memory_buffer_basic() {
    // 创建内存缓冲区
    let mut buffer = SafeMemoryBuffer::new(1024).unwrap();
    assert_eq!(buffer.size(), 1024);
    
    // 写入数据
    let data = "Hello, Safe Memory!".as_bytes();
    buffer.copy_from_slice(data).unwrap();
    
    // 读取数据
    let read_data = buffer.as_slice();
    assert_eq!(&read_data[..data.len()], data);
    
    // 创建子缓冲区
    let sub_buffer = buffer.sub_buffer(0, data.len()).unwrap();
    assert_eq!(sub_buffer.size(), data.len());
    assert_eq!(sub_buffer.as_slice(), &data[..]);
    
    // 测试边界检查
    let result = buffer.sub_buffer(0, 2048);
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::BufferTooSmall(_)));
}

// 测试SafeMemoryBuffer的复制功能
#[test]
fn test_safe_memory_buffer_copy() {
    let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // 从切片创建缓冲区
    let source = SafeMemoryBuffer::from_slice(&data).unwrap();
    assert_eq!(source.size(), data.len());
    assert_eq!(source.as_slice(), &data);
    
    // 创建目标缓冲区
    let mut dest = SafeMemoryBuffer::new(data.len()).unwrap();
    
    // 复制数据
    let copy_size = CopyUtils::safe_copy(&mut dest, &source).unwrap();
    assert_eq!(copy_size, data.len());
    assert_eq!(dest.as_slice(), &data);
    
    // 测试目标缓冲区太小的情况
    let mut small_dest = SafeMemoryBuffer::new(data.len() - 2).unwrap();
    let result = CopyUtils::safe_copy(&mut small_dest, &source);
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::BufferTooSmall(_)));
}

// 测试SafeCString
#[test]
fn test_safe_c_string() {
    // 创建C字符串
    let c_string = SafeCString::new("Hello, Safe C String!").unwrap();
    assert_eq!(c_string.as_str(), "Hello, Safe C String!");
    assert_eq!(c_string.len(), "Hello, Safe C String!".len());
    
    // 检查C风格指针
    let c_ptr = c_string.as_ptr();
    assert!(!c_ptr.is_null());
    
    // 测试包含空字符的字符串
    let result = SafeCString::new("Hello\0World");
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::InvalidString(_)));
    
    // 测试空字符串
    let empty_string = SafeCString::new("").unwrap();
    assert_eq!(empty_string.as_str(), "");
    assert_eq!(empty_string.len(), 0);
}

// 测试配置管理
#[test]
fn test_config_management() {
    // 创建配置对象
    let mut config = Config::new();
    
    // 设置配置值
    config.set("app.name", ConfigValue::String("test-app".to_string())).unwrap();
    config.set("app.version", ConfigValue::String("1.0.0".to_string())).unwrap();
    config.set("app.debug", ConfigValue::Bool(true)).unwrap();
    config.set("app.max_connections", ConfigValue::Uint(100)).unwrap();
    config.set("app.timeout", ConfigValue::Int(-1)).unwrap();
    config.set("app.score", ConfigValue::Float(99.9)).unwrap();
    
    // 获取配置值
    let name = config.get("app.name").unwrap().as_string().unwrap();
    let version = config.get("app.version").unwrap().as_string().unwrap();
    let debug = config.get("app.debug").unwrap().as_bool().unwrap();
    let max_connections = config.get("app.max_connections").unwrap().as_uint().unwrap();
    let timeout = config.get("app.timeout").unwrap().as_int().unwrap();
    let score = config.get("app.score").unwrap().as_float().unwrap();
    
    // 验证值
    assert_eq!(name, "test-app");
    assert_eq!(version, "1.0.0");
    assert_eq!(debug, true);
    assert_eq!(max_connections, 100);
    assert_eq!(timeout, -1);
    assert!((score - 99.9).abs() < 0.0001);
    
    // 测试不存在的键
    let result = config.get("app.nonexistent");
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::KeyNotFound(_)));
    
    // 测试类型不匹配
    let result = config.get("app.name").unwrap().as_bool();
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::TypeMismatch(_)));
    
    // 序列化和反序列化
    let serialized = config.serialize().unwrap();
    let deserialized = Config::deserialize(&serialized).unwrap();
    
    // 验证反序列化结果
    let deserialized_name = deserialized.get("app.name").unwrap().as_string().unwrap();
    assert_eq!(deserialized_name, "test-app");
}

// 测试安全配置对象
#[test]
fn test_safe_zenrs_config() {
    // 创建安全配置对象
    let config_ptr = SafeZenrsConfig::create().unwrap();
    assert!(!config_ptr.is_null());
    
    // 设置配置值
    SafeZenrsConfig::set(
        config_ptr,
        "ffi.test.string",
        ConfigValue::String("test-string-value".to_string())
    ).unwrap();
    
    SafeZenrsConfig::set(
        config_ptr,
        "ffi.test.bool",
        ConfigValue::Bool(true)
    ).unwrap();
    
    SafeZenrsConfig::set(
        config_ptr,
        "ffi.test.uint",
        ConfigValue::Uint(42)
    ).unwrap();
    
    // 获取配置值
    let string_value = SafeZenrsConfig::get(config_ptr, "ffi.test.string").unwrap();
    let bool_value = SafeZenrsConfig::get(config_ptr, "ffi.test.bool").unwrap();
    let uint_value = SafeZenrsConfig::get(config_ptr, "ffi.test.uint").unwrap();
    
    // 验证值
    assert_eq!(string_value.as_string().unwrap(), "test-string-value");
    assert_eq!(bool_value.as_bool().unwrap(), true);
    assert_eq!(uint_value.as_uint().unwrap(), 42);
    
    // 序列化配置
    let serialized = SafeZenrsConfig::serialize(config_ptr).unwrap();
    assert!(!serialized.is_empty());
    
    // 释放配置对象
    SafeZenrsConfig::free(config_ptr).unwrap();
}

// 测试回调管理
#[test]
fn test_callback_management() {
    // 注册回调
    let callback_id = register_string_callback(|input| {
        format!("processed: {}", input)
    }).unwrap();
    
    // 执行回调
    let input = "test input".as_bytes();
    let result = execute_callback(callback_id, input).unwrap();
    let result_str = String::from_utf8(result).unwrap();
    assert_eq!(result_str, "processed: test input");
    
    // 多次执行回调
    let input2 = "another input".as_bytes();
    let result2 = execute_callback(callback_id, input2).unwrap();
    let result_str2 = String::from_utf8(result2).unwrap();
    assert_eq!(result_str2, "processed: another input");
    
    // 注销回调
    unregister_callback(callback_id).unwrap();
    
    // 尝试执行已注销的回调
    let result = execute_callback(callback_id, input);
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::CallbackNotFound(_)));
}

// 测试线程安全性
#[test]
fn test_thread_safety() {
    use std::thread;
    use std::sync::atomic::{AtomicUsize, Ordering};
    
    // 创建一个共享的计数器
    let counter = Arc::new(AtomicUsize::new(0));
    
    // 注册一个线程安全的回调
    let counter_clone = Arc::clone(&counter);
    let callback_id = register_string_callback(move |input| {
        // 增加计数器
        counter_clone.fetch_add(1, Ordering::Relaxed);
        format!("thread: {}, input: {}", thread::current().name().unwrap_or("unknown"), input)
    }).unwrap();
    
    // 创建多个线程同时执行回调
    let mut threads = vec![];
    for i in 0..10 {
        let callback_id_clone = callback_id;
        let thread = thread::Builder::new()
            .name(format!("thread-{}", i))
            .spawn(move || {
                let input = format!("input from thread {}", i).as_bytes();
                let result = execute_callback(callback_id_clone, input).unwrap();
                String::from_utf8(result).unwrap()
            })
            .unwrap();
        threads.push(thread);
    }
    
    // 等待所有线程完成
    for thread in threads {
        let result = thread.join().unwrap();
        assert!(result.contains("input from thread"));
    }
    
    // 验证回调被执行了10次
    assert_eq!(counter.load(Ordering::Relaxed), 10);
    
    // 清理
    unregister_callback(callback_id).unwrap();
}

// 测试工具函数
#[test]
fn test_utils() {
    // 测试字符串工具
    let mut buffer = SafeMemoryBuffer::new(100).unwrap();
    StringUtils::to_c_string("test string", &mut buffer).unwrap();
    let c_str = std::ffi::CStr::from_bytes_until_nul(buffer.as_slice()).unwrap();
    assert_eq!(c_str.to_str().unwrap(), "test string");
    
    // 测试数值工具
    let mut num_buffer = SafeMemoryBuffer::new(8).unwrap();
    NumberUtils::u64_to_bytes(123456789, &mut num_buffer).unwrap();
    let num = NumberUtils::bytes_to_u64(&num_buffer).unwrap();
    assert_eq!(num, 123456789);
    
    // 测试边界检查
    let small_buffer = SafeMemoryBuffer::new(4).unwrap();
    let result = NumberUtils::bytes_to_u64(&small_buffer);
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::BufferTooSmall(_)));
}

// 测试错误处理
#[test]
fn test_error_handling() {
    // 测试缓冲区太小错误
    let small_buffer = SafeMemoryBuffer::new(5).unwrap();
    let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let result = small_buffer.copy_from_slice(&data);
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::BufferTooSmall(_)));
    
    // 测试无效字符串错误
    let result = SafeCString::new("contains null\0character");
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::InvalidString(_)));
    
    // 测试键未找到错误
    let config = Config::new();
    let result = config.get("nonexistent.key");
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::KeyNotFound(_)));
    
    // 测试类型不匹配错误
    let mut config = Config::new();
    config.set("test.key", ConfigValue::String("string value".to_string())).unwrap();
    let result = config.get("test.key").unwrap().as_bool();
    assert!(result.is_err());
    assert!(matches!(result.unwrap_err(), FFIError::TypeMismatch(_)));
}